home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1997 August / Walnut Creek CDROM.7z / LISTINGS / V_13_04 / CHAPMAN2 / CHAPMAN2.ZIP / UTILS.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-23  |  5.5 KB  |  191 lines

  1. /* utils.cpp / text and pointer manipulation utilities for error reporter */
  2.  
  3. #include <stdio.h>
  4. #include <ctype.h>                      /* isalpha() etc. */
  5. #include <string.h>                     /* strncpy() etc. */
  6. #include <stdlib.h>
  7. #include "utils.hpp"
  8.  
  9. int skipblanks(const char *s)
  10. {
  11.     /* skip leading white space and return a count of characters skipped. */
  12.  
  13.     const char *start = s;
  14.  
  15.     while (*s && isspace(*s))
  16.         ++s;
  17.     return s - start;
  18.  
  19. }  /* end of skipblanks() */
  20.  
  21. int skip_ident(const char *s)
  22. {
  23.     /* skip leading alphanumeric characters (a-zA-Z0-9_) and return a */
  24.     /* count of characters skipped. */
  25.  
  26.     const char *start = s;
  27.  
  28.     while (*s && (isalpha(*s) || isdigit(*s) || *s == '_'))
  29.         ++s;
  30.     return s - start;
  31.  
  32. }  /* end of skip_ident() */
  33.  
  34. char *newstring(const char *s,int len)
  35. {
  36.     /* allocate storage for some text. if the length is specified we */
  37.     /* use that; otherwise we use strlen(s). */
  38.  
  39.     char *new_s;
  40.  
  41.     if (s == 0)
  42.         return 0;
  43.     if (len == 0)                       /* default: find length of string */
  44.         len = strlen(s);
  45.     new_s = (char *) malloc(len + 1);   /* allocate space for '\0' too */
  46.     strncpy(new_s,s,len);
  47.     new_s[len] = '\0';                  /* in case strncpy() didn't */
  48.     return new_s;
  49.  
  50. }  /* end of newstring() */
  51.  
  52. void read_continued_line(FILE *f,char *line,int linelen)
  53. {
  54.     /* read a complaint file line, merging continuation lines together. */
  55.  
  56.     size_t thislen,lastlen;
  57.  
  58.     line[0] = '\0';                     /* clear old data */
  59.     fgets(line,linelen,f);              /* get first line of text */
  60.     thislen = strlen(line);
  61.     if (thislen == 0)                   /* EOF? done */
  62.         return;
  63.  
  64.     /* add continuation lines, each terminated by '\\'. effectively we */
  65.     /* quote the trailing newline. */
  66.  
  67.     lastlen = 0;
  68.     while (thislen != lastlen && thislen > 1 &&
  69.            line[thislen - 1] == '\n' &&
  70.            line[thislen - 2] == '\\') {
  71.         line[thislen - 2] = '\n';       /* remove '\\', '\n', */
  72.         line[thislen - 1] = '\0';       /* restore '\n' */
  73.         lastlen = thislen - 1;
  74.         if (fgets(line + lastlen,linelen - lastlen,f) == 0)  /* next line */
  75.             line[lastlen] = '\0';       /* keep it valid */
  76.         thislen = strlen(line);
  77.     }  /* end of while() */
  78.  
  79. }  /* end of read_continued_line() */
  80.  
  81. /***************************** class ptr_stack *****************************/
  82.  
  83. const long INITSIZE = 32L;
  84. const long MAXSIZE = 1024L;             /* when we stop doubling size */
  85.  
  86. ptr_stack::ptr_stack(void)
  87. {
  88.     top_idx = -1L;                      /* where top elem is - pre-increment */
  89.     size = INITSIZE;
  90.     elems = (void **) malloc(size * sizeof(void *));
  91.  
  92. }  /* end of ptr_stack::ptr_stack() */
  93.  
  94. ptr_stack::ptr_stack(const ptr_stack &other)  /* copy constructor */
  95. {
  96.     /* since we don't delete the elements stored in the stack when the */
  97.     /* stack is deleted, nothing special must be done except to copy the */
  98.     /* array holding them. */
  99.  
  100.     int i;
  101.  
  102.     size = other.size;
  103.     elems = (void **) malloc(size * sizeof(void *));
  104.     for (i = 0; i < size; ++i)
  105.         elems[i] = other.elems[i];
  106.     top_idx = other.top_idx;
  107.  
  108. }  /* end of ptr_stack::ptr_stack(ptr_stack &) */
  109.  
  110. ptr_stack &ptr_stack::operator =(const ptr_stack &other)  /* assignment */
  111. {
  112.     /* we delete everything currently in this stack and copy over the */
  113.     /* things in the other stack. */
  114.  
  115.     int i;
  116.  
  117.     if (this != &other) {               /* guard against self-assignment */
  118.         free(elems);
  119.  
  120.         /* this is from the copy constructor; it's not worth the overhead of */
  121.         /* an init() function. */
  122.  
  123.         size = other.size;
  124.         elems = (void **) malloc(size * sizeof(void *));
  125.         for (i = 0; i < size; ++i)
  126.             elems[i] = other.elems[i];
  127.         top_idx = other.top_idx;
  128.     }
  129.     return *this;
  130.  
  131. }  /* end of ptr_stack::operator =() */
  132.  
  133. ptr_stack::~ptr_stack(void)
  134. {
  135.     /* clean up the mess. */
  136.  
  137.     free(elems);
  138.  
  139. }  /* end of ptr_stack::~ptr_stack() */
  140.  
  141. void *ptr_stack::push(void *op)
  142. {
  143.     /* push the element onto the stack (no type checking). expand the stack */
  144.     /* to prevent overflow, doubling the size until we reach MAXSIZE. */
  145.     /* afterwards, increase the size only by MAXSIZE. */
  146.  
  147.     long i,newsize;
  148.     void **newary;
  149.                                         /* pre-increment */
  150.     if (++top_idx >= size) {            /* expand on overflow */
  151.         newsize = size + ((size >= MAXSIZE) ? MAXSIZE : size);
  152.         newary = (void **) malloc(newsize * sizeof(void *));
  153.         for (i = 0L; i < size; ++i)
  154.             newary[i] = elems[i];
  155.         free(elems);
  156.         elems = newary;
  157.         size = newsize;
  158.     }
  159.     elems[top_idx] = op;
  160.     return op;
  161.  
  162. }  /* end of ptr_stack::push() */
  163.  
  164. void *ptr_stack::pop(void)
  165. {
  166.     /* remove the top element from the stack and return it. */
  167.  
  168.     if (top_idx < 0L)
  169.         return 0;
  170.     return elems[top_idx--];            /* post-decrement */
  171.  
  172. }  /* end of ptr_stack::pop() */
  173.  
  174. void *ptr_stack::top(void) const
  175. {
  176.     /* return the top element of the stack without removing it. */
  177.  
  178.     if (top_idx < 0L)
  179.         return 0;
  180.     return elems[top_idx];              /* leave top_idx alone! */
  181.  
  182. }  /* end of ptr_stack::top() */
  183.  
  184. long ptr_stack::elem_count(void)
  185. {
  186.     /* how many elements have been pushed onto the stack? */
  187.  
  188.     return top_idx + 1L;
  189.  
  190. }  /* end of ptr_stack::elem_count() */
  191.